[![License](https://img.shields.io/badge/License-BSD_3--Clause-yellow.svg)](https://opensource.org/licenses/BSD-3-Clause)
[![Release](https://github.com/mbrav/telnum-gen/actions/workflows/release.yml/badge.svg?event=release)](https://github.com/mbrav/telnum-gen/actions/workflows/release.yml)
[![wakatime](https://wakatime.com/badge/user/54ad05ce-f39b-4fa3-9f2a-6fe4b1c53ba4/project/54d9c5f4-7e6c-4485-b7ad-72a4bce96f64.svg)](https://wakatime.com/badge/user/54ad05ce-f39b-4fa3-9f2a-6fe4b1c53ba4/project/54d9c5f4-7e6c-4485-b7ad-72a4bce96f64)
[![tokei](https://tokei.rs/b1/github/mbrav/telnum-gen?category=lines)](https://tokei.rs/b1/github/mbrav/telnum-gen)

# telnum-gen

Telephone number generator using the Cartesian product methods in Python and Rust.

## Python Implementation

The Python implementation uses a [Cartesian product](https://en.wikipedia.org/wiki/Cartesian_product) generator from `itertools.product` which takes advantage of C optimizations.

To run program:

```bash
python3 src
```

Additional args are possible:

```bash
python3 src --country_code 8 --prefix 999 --chunk_size 1000 --file result.txt
```

The `--chunk_size` flag changes the number of elements that are stored in memory before being dumped to a file. Otherwise, to store a combination of 10 digit phone numbers will require more than 10GB of RAM.

In Python 3.10, the program will take roughly:

- 8 seconds to run to generate all possible phone numbers for `8 999 xxx xxxx`.
- 14 minutes to run to generate all possible phone numbers for `8 99x xxx xxxx`.
- 2.5 hours to run to generate all possible phone numbers for `8 9xx xxx xxxx`.

<details>
<summary>
Profiling
</summary>

This will run all phone number permutations with chunk_size set to 10000 and prefix set to "999".

```bash
pip3 install snakeviz
```

```bash
python3 -m cProfile -o phone_gen.prof src/__main__.py && snakeviz phone_gen.prof
```

</details>

## Rust Implementation (2x Faster)

As of [0.1.0](https://github.com/mbrav/telnum-gen/releases/tag/0.1.0), the Rust implementation of the same Python program has many areas where it can be optimized, potentially making it 100X faster. Additional improvements can be made by implementing an iterator, rather than a naive list comprehension, and optimizing the algorithm that calculates the cartesian_product. Despite these numerous fallbacks, the program is 2X faster compared to its Python counterpart. The timing of the program is also much more deterministic than its Python counterpart.

The Rust implementation will take roughly:

- 5 seconds to run to generate all possible phone numbers for `8 999 xxx xxxx`.
- 8 minutes to run to generate all possible phone numbers for `8 99x xxx xxxx`.
- 1.2 hours to run to generate all possible phone numbers for `8 9xx xxx xxxx`.

To run the program first install Rust's toolchain with [`rustup`](https://rustup.rs/), then run:

```bash
cd rust
```

Run the program with build optimizations where arguments after `--` are country code, prefix and output file (arbitrary path supported):

```bash
cargo run -- --country-code 8 --prefix 999 --file result.txt
```

The output will be the following:

```txt
telnum_gen v0.1.0
RUNNING PROGRAM
Country Code: 8
Prefix: 999
Output to: result.txt
Elements: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Combinations: 7
Elapsed: 4.894s
```
